package co.gov.medellin.ssti.sub.common.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import co.gov.medellin.ssti.sub.common.excepcion.SUBException;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.service.SubprogramaService;
import co.gov.medellin.ssti.sub.model.service.VflexService;
import co.gov.medellin.ssti.sub.model.vo.SubprogramaVO;
import co.gov.medellin.ssti.sub.model.vo.VflexVO;

/**
 * Clase utility que realiza diversas consultas para ser usada por Direct Web
 * Remoting.
 * 
 * @author Consultsoft4
 * 
 */
public class VisualHelper {
	// injected beans.
	public VflexService vflexServiceImpl;
	public SubprogramaService subprogramaServiceImpl;

	public void setVflexServiceImpl(VflexService vflexServiceImpl) {
		this.vflexServiceImpl = vflexServiceImpl;
	}

	public void setSubprogramaServiceImpl(
			SubprogramaService subprogramaServiceImpl) {
		this.subprogramaServiceImpl = subprogramaServiceImpl;
	}

	private static final Logger logger = Logger.getLogger(VisualHelper.class);

	public String getZonas() {
		ArrayList<VflexVO> zonas = new ArrayList<VflexVO>();
		try {
			zonas = (ArrayList<VflexVO>) vflexServiceImpl
					.findVflex(VflexService.ZONA);
		} catch (DAOException e) {
			SUBException.logDebugError("", e);
		}

		return collectionToSelect(zonas);
	}

	public String getComunas() {
		ArrayList<VflexVO> comunas = new ArrayList<VflexVO>();
		try {
			comunas = (ArrayList<VflexVO>) vflexServiceImpl
					.findVflex(VflexService.COMUNA);
		} catch (DAOException e) {
			SUBException.logDebugError("", e);
		}
		return collectionToSelect(comunas);
	}

	public String getBarrios() {
		ArrayList<VflexVO> barrios = new ArrayList<VflexVO>();
		try {
			barrios = (ArrayList<VflexVO>) vflexServiceImpl
					.findVflex(VflexService.BARRIO);
		} catch (DAOException e) {
			SUBException.logDebugError("", e);
		}
		return collectionToSelect(barrios);
	}

	public String buscarPadre(String code) {
		String padre = "";
		try {
			padre = vflexServiceImpl.findCodePadreByCodeHijo(new Long(code))
					.toString();
			padre += "|"
					+ vflexServiceImpl.findCodePadreByCodeHijo(new Long(padre))
							.toString();
		} catch (DAOException e) {
			SUBException.logDebugError("", e);
		}
		return padre;

	}

	/**
	 * Metodo que obtiene las comunas correspondientes a la zona seleccionada.
	 * 
	 * @param code
	 *            Codigo de la zona.
	 * @return String tipo json que representa la lista de comunas
	 *         pertenecientes a la zona seleccionada.
	 */
	public String selectZona(String code) {
		Collection<VflexVO> cComunas = null;

		// busca las comunas pertenecientes a la zona.
		if (code != null && !code.equals("")) {
			cComunas = vflexServiceImpl.findVflex(VflexService.COMUNA, code);
		} else {
			cComunas = vflexServiceImpl.findVflex(VflexService.COMUNA);
		}
		return collectionToSelect(cComunas);
	}

	/**
	 * Metodo que retorna el codigo de la zona correspondiente a la comuna.
	 * 
	 * @param code
	 *            Codigo de la comuna.
	 * @return Codigo de la zona a la que pertenece la comuna.
	 */
	public String selectComuna(String code) {
		// Collection<VflexVO> cComunas = null;
		String zona = "";
		if (code != null && !code.equals("")) {
			Long codZona = vflexServiceImpl.findCodePadreByCodeHijo(new Long(
					code));
			zona = (codZona == null ? "" : Long.toString(codZona.longValue()));

			// cComunas = vflexService.findVflex("COMUNA", zona);

		} else {
			System.out.println("else");
			// cComunas = vflexService.findVflex("COMUNA");
		}
		// return collectionToSelect(cComunas);
		return zona;
	}

	public String[] selectComunaPopulateBarrios(String code) {
		String[] ret = new String[2];
		String zona = "";
		Collection<VflexVO> cBarrios = null;
		if (code != null && !code.equals("")) {
			cBarrios = vflexServiceImpl.findVflex(VflexService.BARRIO, code);
			Long codZona = vflexServiceImpl.findCodePadreByCodeHijo(new Long(
					code));
			zona = (codZona == null ? "" : Long.toString(codZona.longValue()));
		} else {
			cBarrios = vflexServiceImpl.findVflex(VflexService.BARRIO);
		}
		ret[0] = removeLineBreak(collectionToSelect(cBarrios));
		ret[1] = zona;
		System.out.println(ret[0]);
		return ret;
	}

	/**
	 * Metodo que retorna un string tipo json representando los subprogramas
	 * correspondientes al programa correspondiente a code, segun el userCode,
	 * userGroupName, userCodeArea.
	 * 
	 * @param code
	 *            Codigo del programa.
	 * @param userCode
	 *            Codigo del usuario.
	 * @param userGroupName
	 *            Grupo del usuario.
	 * @param userCodeArea
	 *            Area del usuario.
	 * @return String tipo json de los subprogramas.
	 */
	public String selectPrograma(String code, Long userCode,
			String userGroupName, Long userCodeArea) {
		if (code == null || code.equals("")) {
			return "[{ \"name\": \"Seleccione una opcion\", \"id\": \"\"}]";
		}
		try {
			Collection<SubprogramaVO> subprogramas = subprogramaServiceImpl
					.findSubprogramaUser(userCode, userGroupName,
							new Long(code), userCodeArea);
			System.out.println("code " + code);
			// se agregan los subprogramas en una coleccion.
			Iterator<SubprogramaVO> it = subprogramas.iterator();
			Collection<SubprogramaVO> collection = new ArrayList<SubprogramaVO>();
			while (it.hasNext()) {
				SubprogramaVO subprogramaVO = it.next();
				collection.add(subprogramaVO);
			}
			// Construir string json.
			StringBuffer select = new StringBuffer(
					"[{ \"name\": \"Seleccione una opcion\", \"id\": \"\"}");
			if (collection != null && collection.size() > 0) {
				select.append(",");
				for (Iterator<SubprogramaVO> i = collection.iterator(); i
						.hasNext();) {
					SubprogramaVO subprogramaVO = (SubprogramaVO) i.next();
					select.append("{ \"name\": \"" + subprogramaVO.getNombre()
							+ "\", \"id\": \"" + subprogramaVO.getCode()
							+ "\"}");
					if (i.hasNext()) {
						select.append(",");
					}
				}
			}
			select.append("]");
			// Eliminar line break.
			Pattern pattern = Pattern.compile("\n");
			Matcher matcher = pattern.matcher(select.toString());
			String str = matcher.replaceAll("");
			// System.out.println("str: " + str);
			return str;
		} catch (NumberFormatException e) {
			logger.error(e);
		} catch (Exception e) {
			logger.error(e);
		}
		return null;
	}

	/**
	 * Metodo que retorna un string tipo json de la Collection id-valor.
	 * 
	 * @param col
	 *            Collection id-valor a ser representada en String json.
	 * @return String json.
	 */
	private String collectionToSelect(Collection<VflexVO> col) {
		StringBuffer select = new StringBuffer(
				"[{ \"name\": \"Seleccione una opcion\", \"id\": \"\"}");
		if (col != null && col.size() > 0) {
			select.append(",");
			for (Iterator<VflexVO> i = col.iterator(); i.hasNext();) {
				VflexVO valorFlex = i.next();
				select.append("{ \"name\": \"" + valorFlex.getDescVflex()
						+ "\", \"id\": \"" + valorFlex.getCode() + "\"}");
				if (i.hasNext()) {
					select.append(",");
				}
			}

		}
		select.append("]");
		// Se debe asegurar que el string no tenga line break que pueda causar
		// error en el javascript, por lo que se remplazan las coincidencias de
		// "\n" por "".
		Pattern pattern = Pattern.compile("\n");
		Matcher matcher = pattern.matcher(select.toString());
		String str = matcher.replaceAll("");
		// System.out.println(str);
		return str;
	}

	private String collectionToSelect(ArrayList<VflexVO> col) {
		String select = "[ { name: 'Seleccione una opcion', id: '0'}, ";
		if (col != null && col.size() > 0) {
			for (Iterator<VflexVO> i = col.iterator(); i.hasNext();) {
				VflexVO valorFlex = i.next();
				select += "{ name:'" + valorFlex.getDescVflex() + "', id:'"
						+ valorFlex.getCode() + "'},";
			}

		}
		select += "{}]";
		return select;
	}

	private String removeLineBreak(String str) {
		// Eliminar line break.
		Pattern pattern = Pattern.compile("\n");
		Matcher matcher = pattern.matcher(str);
		return matcher.replaceAll("");
	}

}
